#pragma once
#include "../CGIPrefix.h"

namespace Alice{
    class CGIVulkanDevice;
	class FenceManager;
    class VulkanFence
	{
    public:
    	enum class EState
    	{
    		// Initial state
    		NotReady,

			// After GPU processed it
			Signaled,
		};
        VkFence mFence;
    	FenceManager* mFenceManager;
    	EState mState;
    	VulkanFence(CGIVulkanDevice*inDevice,FenceManager*inOwner,bool inbCreateSignaled);
    	~VulkanFence();
    	inline VkFence GetHandle() const
    	{
    		return mFence;
    	}
    	inline bool IsSignaled() const
    	{
    		return mState==EState::Signaled;
    	}
    	FenceManager* GetOwner()
    	{
    		return mFenceManager;
    	}
    };
    class VulkanSemaphore
	{
	public:
    	VulkanSemaphore(CGIVulkanDevice& inDevice);
        CGIVulkanDevice& mDevice;
        VkSemaphore mSemaphore;
    	inline VkSemaphore GetHandle() const
    	{
    		return mSemaphore;
    	}
    };
	class FenceManager
	{
	public:
		FenceManager();
		void Init(CGIVulkanDevice*inDevice);
		VulkanFence* AllocateFence(bool bCreateSignaled = false);
		CGIVulkanDevice* mDevice;
		bool WaitForFence(VulkanFence* Fence, uint64 TimeInNanoseconds);
	};
}